import static org.junit.Assert.*;

import java.math.BigDecimal;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;



public class SquareTest {
	
	private static Square square150Temp59humid;
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
	}

	@Before
	public void setUp() throws Exception {
		square150Temp59humid = new Square(150,new BigDecimal("59.01"));
		
	}

	@After
	public void tearDown() throws Exception {
		
	}
	
	@Test
	public void constructor_SingleCase(){
		Square square = new Square(100,new BigDecimal("20.02"));
		assertEquals(100,square.getTemperature(TemperatureScale.CELCIUS),0.001);
		assertEquals(new BigDecimal("20.02"),square.getHumidity());
		assertTrue(square.getBorder(3));
		assertTrue(square.getBorder(1));
		assertTrue(square.getBorder(6));
	}
	
	@Test
	public void setTemperature_TrueCase() {
		square150Temp59humid.setTemperature(3000, TemperatureScale.CELCIUS);
		assertEquals ( 3000, square150Temp59humid.getTemperature(TemperatureScale.CELCIUS), 0.001);
	}
	
	@Test(expected = IllegalArgumentException.class)
	public void setTemperature_ToLow() {
		square150Temp59humid.setTemperature(-2000,TemperatureScale.CELCIUS);
	}
	
	@Test
	public void isValidTemperature_ToHigh(){
		assertFalse(Square.isValidTemperature(5001));
	}
	
	@Test
	public void getTemperature_Fahrenheit() {
		assertEquals(square150Temp59humid.getTemperature(TemperatureScale.FAHRENHEIT), 302, 0.001);
	}
	
	@Test
	public void getTemperature_Kelvin() {
		assertEquals(square150Temp59humid.getTemperature(TemperatureScale.KELVIN),423.15, 0.001);
	}
	
	@Test
	public void coldDamage_TrueCase(){
		Square square = new Square(-50,new BigDecimal("4"));
		assertEquals(square.coldDamage(),4);
	}
	
	@Test
	public void coldDamage_NoDamage(){
		assertEquals(square150Temp59humid.coldDamage(),0);
	}
	
	@Test
	public void heatDamage_TrueCase(){
		assertEquals(square150Temp59humid.heatDamage(), 7);
	}
	
	@Test
	public void heatDamage_NoDamage(){
		Square square = new Square(34, new BigDecimal("4"));
		assertEquals(square.heatDamage(), 0);
	}
	
	
//	These tests are for private methods.
//  If you want to run these test you have to make the used methods public.
//	
//	@Test
//	public void setHeatDamageLowerBoundary_SingleCase(){
//		Square.setHeatDamageLowerBoundary(-500);
//		assertEquals(square150Temp59humid.getHeatDamageLowerBoundary(), -500);
//		
//	}
//	
//	@Test
//	public void setHeatDamageRate_TrueCase(){
//		Square.setHeatDamageRate(5);
//		assertEquals(square150Temp59humid.getHeatDamageRate(), 5);
//	}
	
	@Test (expected = IllegalArgumentException.class)
	public void setHeatDamageRate_NegativeRate() throws Exception{
		Square.setHeatDamageRate(-5);
	}
	
	@Test
	public void setHumidity_TrueCase(){
		square150Temp59humid.setHumidity(new BigDecimal("99.99"));
		assertEquals(square150Temp59humid.getHumidity(),new BigDecimal("99.99") );
	}
	
	@Test 
	public void isValidHumidity_ToLow(){
		assertFalse(square150Temp59humid.isValidHumidity(new BigDecimal("-1")));
	}
	
	@Test 
	public void isValidHumidity_ToHigh(){
		assertFalse(square150Temp59humid.isValidHumidity(new BigDecimal("100.5")));
	}
	
	@Test
	public void rustDamage_SingleCase(){
		assertEquals(square150Temp59humid.rustDamage(), 4);
	}
	
	@Test
	public void isSlippery_SlipperyFloorMaterial(){
		square150Temp59humid.setSlipperyFloorMaterial(true);
		assertTrue(square150Temp59humid.isSlippery());
	}
	
	@Test
	public void isSlippery_Aquaplaning(){
		square150Temp59humid.setHumidity(new BigDecimal("100"));
		assertTrue(square150Temp59humid.isSlippery());
	}
	
	@Test
	public void isSlippery_LayerOfIce() {
		square150Temp59humid.setTemperature(-10,TemperatureScale.CELCIUS);
		assertTrue(square150Temp59humid.isSlippery());
	}
	
	@Test
	public void isSlippery_FalseCase(){
		assertFalse(square150Temp59humid.isSlippery());
	}
	
	@Test
	public void setBorder_SingleCase(){
		square150Temp59humid.removeBorder(1,2,3);
		square150Temp59humid.setBorder(1,3,4);
		assertTrue(square150Temp59humid.getBorder(1));
		assertTrue(square150Temp59humid.getBorder(3));
		assertFalse(square150Temp59humid.getBorder(2));
	}
	
	@Test
	public void removeBorder_SingleCase(){
		square150Temp59humid.removeBorder(4,5,6);
		assertFalse(square150Temp59humid.getBorder(6));
		assertFalse(square150Temp59humid.getBorder(4));
		assertFalse(square150Temp59humid.getBorder(5));

	}
	
	@Test 
	public void isValidBorder_unvalidBorder(){
		assertFalse(Square.isValidBorder(7));
	}
	
	@Test
	public void mergeWith_SingleCase() {
		Square square2 = new Square(50,new BigDecimal("0"));
		square150Temp59humid.mergeWith(square2, 3);
		assertFalse(square150Temp59humid.getBorder(3));
		assertFalse(square2.getBorder(3));
		assertEquals(square2.getHumidity(), new BigDecimal("29.50"));
		assertEquals(square150Temp59humid.getHumidity(),new BigDecimal("29.50") );
		assertEquals(square2.getTemperature(TemperatureScale.CELCIUS),280.04, 0.001);
		assertEquals(square150Temp59humid.getTemperature(TemperatureScale.CELCIUS), 280.04, 0.001);
	}
	
	
	
	
	

}
